import { Injectable } from "@nestjs/common";
import { CreateApiDto } from "./dto/create-api.dto";
import { UpdateApiDto } from "./dto/update-api.dto";
import { Like, Repository } from "typeorm";
import { Api } from "@/modules/system/api/entities/api.entity";
import { InjectRepository } from "@nestjs/typeorm";
import { ResultData } from "@/common/utils/result";
import { instanceToPlain } from "class-transformer";
import { generateMenuTree } from "@/common/utils/common";
import { Menu } from "@/modules/system/menu/entities/menu.entity";

@Injectable()
export class ApiService {
    constructor(
        @InjectRepository(Api)
        private readonly apiRepository: Repository<Api>,
        @InjectRepository(Menu)
        private readonly menuRepository: Repository<Menu>
    ) {
    }
    
    async create(createApiDto: CreateApiDto) {
        return ResultData.ok(instanceToPlain(await this.apiRepository.save(createApiDto)));
    }
    
    async findApiByMenuTree() {
        const generateTree = (data, parentId) => {
            return data.reduce((tree, menu) => {
                if (menu.parentId === parentId) {
                    const children = generateTree(data, menu.id);
                    if (children.length > 0) {
                        menu.children = [...children, ...menu.children];
                    }
                    tree.push(menu);
                }
                return tree;
            }, []);
        };
        
        const res = await this.menuRepository.find({
            order: {
                sort: "DESC",
                id: "DESC"
            },
            select: {
                api: {
                    id: true,
                    apiName: true,
                    apiUrl: true,
                    method:true,
                }
            },
            relations: ["api"]
        });
        
        res.forEach(v => {
            // @ts-ignore
            v.ids = v.id + 1000000;
            // @ts-ignore
            v.children = v.api.map(a => ({
                ...a,
                ids: a.id,
                value: a.id,
                label: a.apiName,
                menuName: a.apiName,
                apiUrl: a.apiUrl,
                menuType: 4,
                menuId: v.id,
            }));
            delete v.api;
        });
        
        return ResultData.ok(instanceToPlain(generateTree(res.map(v => ({
            ...v,
            // @ts-ignore
            value: v.ids,
            label: v.menuName
        })), -1)));
    }
    
    async findAll(findAllDto) {
        console.log("findAllDto", findAllDto);
        const { page, size, apiName, apiUrl, menuId } = findAllDto;
        const take = size || 15;
        const skip = ((page || 1) - 1) * take;
        const where = {
            ...(menuId === 0 || menuId ? { menuId } : null),
            ...(apiUrl ? { apiUrl: Like(`%${apiUrl}%`) } : null),
            ...(apiName ? { apiName: Like(`%${apiName}%`) } : null)
        };
        return ResultData.rowOk(instanceToPlain(await this.apiRepository.findAndCount({
            order: {
                id: "DESC"
            },
            where,
            // relations: {
            //     roles: true
            // },
            skip,
            take
        })));
    }
    
    findOne(id: number) {
        return `This action returns a #${id} api`;
    }
    
    async update(id: number, updateApiDto: UpdateApiDto) {
        return ResultData.ok(await this.apiRepository.update(id, updateApiDto), "更新成功");
    }
    
    async remove(id: number) {
        return ResultData.ok(await this.apiRepository.delete(id), "删除成功");
    }
}
